﻿using System;
// 前面我们已经知道，如果S是B的子类且X<S>允许引用类型转换到X<B>，则类X是协变的。
// 那么能反方向的类是逆变的——从X<B>到X<S>。
// 泛化接口支持逆变当泛型参数只出现在输入的位置，且被指定了in修饰符时。
namespace _078_逆变
{
    class Animal { }
    class Bear : Animal { }
    class Camel : Animal { }
    // Stack<T>类实现了IPushable<int T>接口
    class Stack<T> : IPushable<T>
    {
        int position;
        T[] data = new T[100];
        public void Push(T obj) { data[position++] = obj; }
        public T Pop() { return data[--position]; }
    }
    // 泛化接口支持逆变当泛型参数只出现在输入的位置，且被指定了in修饰符时。
    public interface IPushable<in T> { void Push(T obj); }
    class Program
    {
        static void Main(string[] args)
        {
            IPushable<Animal> animals = new Stack<Animal>();
            IPushable<Bear> bears = animals; // 合法
            bears.Push(new Bear());
            //IPushable中没有成员输出类型为T，所以不会出现将animals转换成bears的问题（但是通过这个接口不能实现Pop方法）
        }
    }
}
